 package com.superpai.view.download; 

import java.io.IOException;
import java.io.InputStream;
import java.net.SocketTimeoutException;
import java.util.HashMap;
import java.util.LinkedList;

import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.params.HttpClientParams;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.conn.params.ConnRouteParams;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;

import android.content.Context;
import android.os.AsyncTask;
import android.util.Log;

import com.superpai.utils.AndroidUtils;
import com.superpai.utils.BitmapUtils;


/**
 * @author
 * @date 2011-7-7
 * @Description VIPSHOP 图片下载器
 * @version V1.0 
 */
public class ImageDownloader {
	
	private Context mContext;

	private String mDebugName = "DownLoad";
	
	/** 状态，空闲 **/
	public static final int STATE_IDLE = 0;
	
	/** 状态，正在下载 **/
	public static final int STATE_DOWNLOADING = 1;
	
	/** 状态，下载完成 **/
	public static final int STATE_DOWNLOAD_COMPLETE = 2;
	
	/** 当前下载器的状态 **/
	private int mDowloadState= STATE_IDLE;
	
	/** 下载执行Task **/
	private Downloader mDownloadTask;
	
	/** 下载任务队列 **/
	private LinkedList<DownloadObj> mDownLoadStack = new LinkedList<DownloadObj>();
	
	/** 下载任务队列备份，用于暂停任务和重新开始任务 **/
	private LinkedList<DownloadObj> mDownLoadBackupStack = new LinkedList<DownloadObj>();
	
	/** 下载监听器 **/
	private OnDownLoadFileListener listener;
	
	/** 下载返回信息，下载到图片 **/
	public static final int DOWN_IMAGE = 1;
	
	/** 下载返回信息，重新下载 **/
	public static final int DOWN_AGAIN = 2;
	
	/** 下载返回信息，下载或解析出错 **/
	public static final int DOWN_ERROR = 3;
	
	private HttpClient mHttpClient;
	
	private HashMap<String, Boolean> mDownloadFileMap;
	
	public ImageDownloader(Context context, HashMap<String, Boolean> fileMap){
		
		this.mContext = context;
		mDownloadFileMap = fileMap;
	}
	
	/**
	 * 添加下载任务到下载列表中
	 *
	 * @param dowloadObj 下载对象
	 * @return 
	 */
	public void addDownLoadTask(DownloadObj dowloadObj){
		
		mDownLoadStack.addFirst(dowloadObj);
	}
	
	/**
	 * 如果任务存在，则移至顶层
	 *
	 * @param dowloadObj 下载对象
	 * @return 
	 */
	public void addDownLoadTask2Top(DownloadObj dowloadObj){
		
		if(mDownLoadStack.contains(mDownLoadStack)){
			mDownLoadStack.remove(mDownLoadStack);
		}
		mDownLoadStack.addFirst(dowloadObj);
	}
	
	/**
	 * 移出下载队列
	 *
	 * @param downloadObj
	 * @return 
	 */
	public void removeLoadTask(DownloadObj downloadObj)
	{
		mDownLoadStack.remove(downloadObj);
		Log.v(mDebugName, "(Downloader)remove:" + downloadObj.getFileName());
	}
	
	/**
	 * 开始下载任务
	 *
	 * @return 
	 */
	public void startDownload()
	{
		mDowloadState = STATE_DOWNLOADING;
		
		if(mDownloadTask==null){
			
			mDownloadTask = new Downloader();
			mDownloadTask.startDownload();
			mDownloadTask.execute();
			
			Log.e(mDebugName, "(Downloader)开始下载!");
		}else{
			mDownloadTask.startDownload();
		}
	}
	
	/**
	 * 终止下载任务
	 *
	 * @return 
	 */
	public void stopDownLoad(boolean isShutdown)
	{
		if(mDownloadTask!=null)
		{
			mDownLoadStack.clear();
			mDownloadTask.stopDownload(isShutdown);
		}
	}
	
	/**
	 * 下载监听器，通过监听器得到下载到的stream流
	 *
	 * @param listener
	 * @return 
	 */
	public void setListener(OnDownLoadFileListener listener) {
		this.listener = listener;
	}

	public void setDebugName(String name){
		this.mDebugName = name;
	}
	 
	/**
	 * 数据流连接
	 * 
	 * @param url
	 * @throws ClientProtocolException
	 * @throws IOException
	 * @return InputStream
	 * @throws
	 */
	private InputStream doGet4stream(String url) throws ClientProtocolException, IOException {
		
		HttpParams httpParams = new BasicHttpParams();
		
		//判断手机客户端连接的cmwap网络，设置代理
		if(AndroidUtils.isWap()){
			HttpHost proxy = new HttpHost("10.0.0.172", 80);
			httpParams.setParameter(ConnRouteParams.DEFAULT_PROXY, proxy);
		}
		
        HttpConnectionParams.setConnectionTimeout(httpParams, 20 * 1000);
        HttpConnectionParams.setSoTimeout(httpParams, 20 * 1000);
        HttpConnectionParams.setSocketBufferSize(httpParams, 8192);
       
        HttpClientParams.setRedirecting(httpParams, true);

        String userAgent = "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.2) Gecko/20100115 Firefox/3.6";
        HttpProtocolParams.setUserAgent(httpParams, userAgent);

        
        mHttpClient = new DefaultHttpClient(httpParams);
        
		HttpGet httpRequest = new HttpGet(url); 

        /*发送请求并等待响应 */
        HttpResponse httpResponse = mHttpClient.execute(httpRequest);
        
        mHttpClient = null;
        if(httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK){
            return httpResponse.getEntity().getContent();
		}else{
			Log.e("debug", "图片下载异常: " + httpResponse.getStatusLine().getStatusCode());
		}
        return null;
	}
	
	/**
	 * @date 2011-7-7 
	 * @version V1.0
	 * @description 下载任务执行器
	 */
	class Downloader extends AsyncTask{

		boolean isDownload;
		
		@Override
		protected Object doInBackground(Object... params){
			
			mDowloadState = STATE_DOWNLOADING;
			Log.e(mDebugName, "-------开始下载--------");
			while(!mDownLoadStack.isEmpty() && isDownload)
			{
				DownloadObj downloadObj = mDownLoadStack.removeFirst();
				downloadObj.setState(downloadObj.STATE_DOWNLOADING);
				int downloadIndex = downloadObj.getDownIndex();
//				if(listener!=null && isDownload){
//					listener.onDownloadBitmap(downloadIndex);
//				}
				
				try {
					InputStream dataStream = null;
					if(mDownloadFileMap.containsKey(downloadObj.getFileName()))
					{
						//直接从本地文件读取 -- 目前没有做缓存
						String fileName = downloadObj.getFileName();
						dataStream = mContext.openFileInput(fileName + ".png");
						
						Log.i(mDebugName, "(doInBackground)从文件系统拿： " + fileName);
					}else {
						String fileUrl = downloadObj.getFileUrl();
						
						Log.v(mDebugName, "(doInBackground)开始下载文件： " + downloadObj.getFileName() + " -- url: " + fileUrl);
						
						dataStream = doGet4stream(fileUrl);
						
						Log.v(mDebugName, "(doInBackground)下载文件完成： " + downloadObj.getFileName());
					}

					//监听器不为空
					if(listener!=null){
						//数据流不为空
						if(dataStream!=null){
							byte dataBytes[] = BitmapUtils.readStream(dataStream);
							dataStream.close();
							boolean isSuccess = listener.onProcessBytes(downloadObj, dataBytes);
							if(isSuccess){
								//图片处理成功，处理后的图片存放于downloadObj中
								
								downloadObj.setState(downloadObj.STATE_DOWNLOAD_COMPLETE);
								
								this.publishProgress(DOWN_IMAGE, downloadObj);
							}else{
								this.publishProgress(DOWN_ERROR, downloadObj);
							}
						}else{
							this.publishProgress(DOWN_ERROR, downloadObj);
						}
					}
				} catch (IOException e) {
					e.printStackTrace();
					Throwable t = e.fillInStackTrace();
					if(t instanceof ConnectTimeoutException || t instanceof SocketTimeoutException){
						
						Log.e(mDebugName, "(doInBackground)连接超时： " + downloadObj.getFileName());
						
						this.publishProgress(DOWN_AGAIN, downloadObj);
//						this.publishProgress(DOWN_ERROR, downloadObj);
					}else{
						
						this.publishProgress(DOWN_ERROR, downloadObj);
					}
						
				}catch (Exception e) {
					Log.e(mDebugName, "(doInBackground)下载文件出错： " + downloadObj.getFileName());
					e.printStackTrace();
					this.publishProgress(DOWN_ERROR, downloadObj);
				}
			}
			mDownloadTask = null;
			mDowloadState = STATE_DOWNLOAD_COMPLETE;
			
			Log.v(mDebugName, "mDownLoadStack: " + mDownLoadStack.isEmpty() + 
					"|isDownload: " + isDownload);
			
			
			Log.e(mDebugName, "-------结束下载--------");
			return null;
		}

		/**
		 * @param values values[0]表示下载是否成功的状态 values[1]为下载到的对象
		 * @return
		 * @throws
		 */
		@Override
		protected void onProgressUpdate(Object... values) {
			
			if(listener!=null && isDownload){
				listener.onProcessDownload(values);
			}else{
				
				Log.v("debug","(ImageDownloader.onProgressUpdate)监听器为空 或者 下载被停止,图片不处理");
				
				DownloadObj downloadObj = (DownloadObj)values[1];
				int loadState = downloadObj.getState();
				if(loadState==DownloadObj.STATE_DOWNLOAD_COMPLETE){
					downloadObj.setState(downloadObj.STATE_RECYLE);
				}else if(loadState==DownloadObj.STATE_DOWNLOADING){
					downloadObj.setState(downloadObj.STATE_WAIT);
				}
				
				if(downloadObj.getDownBitmap()!=null){
					downloadObj.getDownBitmap().recycle();
					downloadObj.setDownBitmap(null);
				}
				
				int result = Integer.parseInt(values[0].toString());
				if(result==ImageDownloader.DOWN_AGAIN){
					downloadObj.setState(downloadObj.STATE_WAIT);
				}
			}
		}

		@Override
		protected void onPostExecute(Object result) {
			super.onPostExecute(result);
		}

		void startDownload(){
			isDownload = true;
		}
	
		void stopDownload(boolean isShutdown){
			
			if(isShutdown && mHttpClient!=null){
				mHttpClient.getConnectionManager().shutdown();
			}
			
			isDownload = false;
		}
	}
	
}
